#![allow(unused)]

use std::array;

/// 可以左移的数组.
#[derive(Debug)]
pub struct EnhancedArray<T, const N: usize> {
    // 数组.
    arr: [T; N],
    // 可能发生左移. 范围: [0, N-1].
    offset: usize,
}

impl<T, const N: usize> EnhancedArray<T, N>
where
    T: Clone,
{
    /// 创建对象, 数组由`default_num`填满.
    pub fn with_num(default_num: T) -> Self {
        let s = array::from_fn(|_| default_num.clone());
        Self { arr: s, offset: 0 }
    }
}

impl<T, const N: usize> EnhancedArray<T, N>
where
    T: Default,
{
    pub fn new() -> Self {
        Self {
            arr: array::from_fn(|_| T::default()),
            offset: 0,
        }
    }
}

impl<T, const N: usize> EnhancedArray<T, N> {
    /// 使用数组构建.
    pub fn with_array(arr: [T; N]) -> Self {
        Self { arr, offset: 0 }
    }

    /// 获取偏移后的下标.
    fn s_index(&self, index: usize) -> usize {
        (index + self.offset) % N
    }

    pub fn get(&self, index: usize) -> &T {
        &self.arr[self.s_index(index)]
    }

    pub fn get_mut(&mut self, index: usize) -> &mut T {
        &mut self.arr[self.s_index(index)]
    }

    // 左移并使用`new_num`填补.
    pub fn left_move(&mut self, new_num: T) {
        self.offset = (self.offset + 1) % (N);
        *self.get_mut(N - 1) = new_num;
    }
}

mod tests {

    #[test]
    fn test_left_move() {
        use super::*;

        let mut array = EnhancedArray::<u32, 16>::new();
        for i in 0..16 {
            *array.get_mut(i) = i as u32;
        }

        // 十次循环
        for _ in 0..10 {
            for i in 0..16 {
                assert_eq!(*array.get(0), i);
                // 循环左移
                array.left_move(*array.get(0));
            }
        }
    }
}
